using System;
using System.Text;
using System.Xml;

namespace OpenComposite.Mapper
{
	#region Class: XsltElement
	public class XsltElement : XmlElement
	{
		internal XsltElement(string elementName, XsltDocument doc)
			: base(XsltStatics.XsltPrefix, elementName, XsltStatics.XsltNamespace, doc)
		{
		}

		private CompileInformations _compileInfos = new CompileInformations();
		internal CompileInformations CompileInformations
		{
			get { return _compileInfos; }
			set { _compileInfos = value; }
		}
	}
	#endregion

	#region Class: CompileInformations
	internal class CompileInformations : ICloneable
	{
		public CompileInformations()
		{
			this.SourceNodeName = "";
			this.SourceSchemaPath = "";

			this.TargetNodeName = "";
			this.TargetSchemaPath = "";

			this.XsltSourceParentNode = null;
			this.XsltVariableNode = null;
		}
		public string SourceNodeName;
		public string SourceSchemaPath;
		public string TargetNodeName;
		public string TargetSchemaPath;
		public XsltElement XsltSourceParentNode;
		public XsltVariable XsltVariableNode;

		#region ICloneable Members

		public object Clone()
		{
			return this.MemberwiseClone();
		}

		#endregion
	}
	#endregion

	#region Class: XsltForEach
	public class XsltForEach : XsltElement
	{
		internal XsltForEach(string select, XsltDocument doc)
			: base(XsltForEach.XsltElementName, doc)
		{
			this.Select = select;
		}

		public string Select
		{
			get { return base.GetAttribute("select"); }
			set { base.SetAttribute("select", value); }
		}

		public override XmlNode Clone()
		{
			return this.CloneNode(true);
		}
		public override XmlNode CloneNode(bool deep)
		{
			XsltDocument xslt = this.OwnerDocument as XsltDocument;
			XsltForEach xforeach = new XsltForEach(this.Select, xslt);
			xforeach.CompileInformations = this.CompileInformations.Clone() as CompileInformations;
			if ( deep ) {
				foreach ( XmlNode xn in this.ChildNodes ) {
					xforeach.AppendChild(xn.Clone());
				}
			}
			return xforeach;
		}

		/// <summary>
		/// Value: "for-each"
		/// </summary>
		public const string XsltElementName = "for-each";
	}
	#endregion

	#region Class: XsltOutput
	public class XsltOutput : XsltElement
	{
		internal XsltOutput(XsltDocument doc)
			: base(XsltOutput.XsltElementName, doc)
		{
			this.Method = "xml";
			this.Encoding = Encoding.UTF8;
			this.Indent = true;
		}

		public string Method
		{
			get { return base.GetAttribute("method"); }
			set { base.SetAttribute("method", value); }
		}
		public Encoding Encoding
		{
			get { return Encoding.GetEncoding(base.GetAttribute("encoding")); }
			set { base.SetAttribute("encoding", value.WebName); }
		}
		public bool Indent
		{
			get { return base.GetAttribute("indent").ToLower().Equals("yes"); }
			set { base.SetAttribute("indent", ( value ? "yes" : "no" )); }
		}

		/// <summary>
		/// Value: "output";
		/// </summary>
		public const string XsltElementName = "output";
	}
	#endregion

	#region Class: XsltTemplate
	public class XsltTemplate : XsltElement
	{
		internal XsltTemplate(string match, XsltDocument doc)
			: base(XsltTemplate.XsltElementName, doc)
		{
			this.Match = match;	
		}
		public string Match
		{
			get { return base.GetAttribute("match"); }
			set { base.SetAttribute("match", value); }
		}
		
		/// <summary>
		/// Value: "";
		/// </summary>
		public const string XsltElementName = "template";
	}
	#endregion

	#region Class: XsltValueOf
	public class XsltValueOf : XsltElement
	{
		internal XsltValueOf(XsltDocument doc)
			: base(XsltValueOf.XsltElementName, doc)
		{
			this.Select = ".";
		}
		public string Select
		{
			get { return base.GetAttribute("select"); }
			set { base.SetAttribute("select", value); }
		}

		/// <summary>
		/// Value: "";
		/// </summary>
		public const string XsltElementName = "value-of";
	}
	#endregion

	#region Class: XsltAttribute
	public class XsltAttribute : XsltElement
	{
		internal XsltAttribute(string name, XsltDocument doc)
			: base(XsltAttribute.XsltElementName, doc)
		{
			this.Name = name;
		}
		
		public new string Name
		{
			get { return base.GetAttribute("name"); }
			set { base.SetAttribute("name", value); }
		}

		/// <summary>
		/// Value: "attribute";
		/// </summary>
		public const string XsltElementName = "attribute";
	}
	#endregion

	#region Class: XsltVariable
	public class XsltVariable : XsltElement
	{
		internal XsltVariable(string name, string select, XsltDocument doc)
			: base(XsltVariable.XsltElementName, doc)
		{
			this.VariableName = name;
			this.Select = select;
		}
		public string VariableName
		{
			get { return base.GetAttribute("name"); }
			set { base.SetAttribute("name", value); }
		}
		public string Select
		{
			get { return base.GetAttribute("select"); }
			set { base.SetAttribute("select", value); }
		}

		/// <summary>
		/// Value: "variable";
		/// </summary>
		public const string XsltElementName = "variable";
	}
	#endregion
}
